﻿Imports ACompany.OrderProcessing.Model
Imports ACompany.OrderProcessing.Services
Imports ACompany.OrderProcessing.Infrastructure
Imports StructureMap

Public Class OrdersController
    Inherits System.Web.Mvc.Controller

    Private OrderService As IOrderService
    Private CustomerService As ICustomerService
    Private ProductService As IProductService

    Public Sub New()

    End Sub

    Public Sub New(ByVal OrderService As IOrderService, _
                   ByVal CustomerService As ICustomerService, _
                   ByVal ProductService As IProductService)

        Me.OrderService = OrderService
        Me.CustomerService = CustomerService
        Me.ProductService = ProductService

    End Sub

    Function Index()
        Return ViewAllOrdersBy("placed")
    End Function

    <AcceptVerbs(HttpVerbs.Post)> _
    Function Index(ByVal formValues As FormCollection)
        Return ViewAllOrdersBy(Request.Form("OrderStatus"))
    End Function

    Function ViewAllOrdersBy(ByVal OrderStatus As String)

        Dim OrderStatusEnum As OrderStatus = FindOrderStatusFrom(OrderStatus)

        Dim Orders As IList(Of Order) = OrderService.GetAllOrdersBy(OrderStatusEnum)

        ViewData("OrderStatus") = New SelectList([Enum].GetNames(GetType(OrderStatus)), OrderStatus)

        Return View("OrderList", Orders)
    End Function

    Public Function Details(ByVal Id As String)

        Dim SelectedOrderId As Guid = New Guid(Id)

        Dim Order As Order = OrderService.FindBy(SelectedOrderId)

        Return View("OrderDetail", Order)
    End Function

    Public Function Add()

        Dim AllCustomers As List(Of Customer) = CustomerService.FindAll
        Dim AllProducts As List(Of Product) = ProductService.FindAll

        ViewData("Customers") = New SelectList(AllCustomers, "Id", "Name")
        ViewData("Products") = New SelectList(AllProducts, "Id", "Name")

        Return View("OrderAdd")

    End Function

    Public Function Process(ByVal Id As String)

        Dim OrderToProcess As Order = OrderService.FindBy(New Guid(Id))

        If OrderToProcess.CanProcess Then
            OrderService.Process(OrderToProcess)
        End If

        Return View("OrderDetail", OrderToProcess)

    End Function

    Public Function Cancel(ByVal Id As String)

        Dim OrderToCancel As Order = OrderService.FindBy(New Guid(Id))

        If OrderToCancel.CanCancel Then
            OrderToCancel.Cancel()
            OrderService.Save(OrderToCancel)
        End If

        Return View("OrderDetail", OrderToCancel)

    End Function

    <AcceptVerbs(HttpVerbs.Post)> _
    Public Function Add(ByVal formValues As FormCollection)
        Dim products As String = Request.Form("Products")
        Dim customerId As String = Request.Form("Customers")

        Dim NewOrder As New Order

        If Not String.IsNullOrEmpty(products) Then
            Dim productIds As String() = Split(products, ",")

            For Each productId In productIds
                NewOrder.Add(ProductService.FindBy(New Guid(productId)))
            Next
        End If

        If Not String.IsNullOrEmpty(customerId) Then
            Dim SelectedCustomer As Customer
            SelectedCustomer = CustomerService.FindBy(New Guid(customerId))
            NewOrder.Customer = SelectedCustomer
            NewOrder.DespatchAddress = SelectedCustomer.Address
        End If

        If NewOrder.GetBrokenRules.Count = 0 Then
            OrderService.Place(NewOrder)
            Return View("OrderDetail", NewOrder)
        Else
            ' Extension method
            ModelState.AddRuleViolations(NewOrder.GetBrokenRules)

            Dim AllCustomers As List(Of Customer) = CustomerService.FindAll
            Dim AllProducts As List(Of Product) = ProductService.FindAll

            ViewData("Customers") = New SelectList(AllCustomers, "Id", "Name")
            ViewData("Products") = New SelectList(AllProducts, "Id", "Name")

            Return View("OrderAdd", NewOrder)

        End If
    End Function

    Public Function FindOrderStatusFrom(ByVal Status As String) As OrderStatus

        Select Case Status
            Case OrderStatus.cancelled.ToString
                Return OrderStatus.cancelled
            Case OrderStatus.placed.ToString
                Return OrderStatus.placed
            Case OrderStatus.shipped.ToString
                Return OrderStatus.shipped
            Case Else
                Return OrderStatus.placed
        End Select

    End Function
End Class
